<template>
  <div class="app-container">
    <!--工具栏-->
    <div class="head-container">
      <div>
        <!-- 搜索 -->
        <el-input
          v-model="query.name"
          size="small"
          clearable
          placeholder="输入名称或者编码搜索"
          style="width: 200px"
          class="filter-item"
          @keyup.enter.native="getData"
        />
        <!--<date-range-picker v-model="query.createTime" class="date-item" />-->
        <span>
          <el-button
            class="filter-item"
            size="mini"
            type="success"
            icon="el-icon-search"
            @click="getData"
            >搜索</el-button
          >
          <el-button
            class="filter-item"
            size="mini"
            type="warning"
            icon="el-icon-refresh-left"
            @click="resetGetData"
            >重置</el-button
          >
        </span>
      </div>
      <el-button
        v-permission="permission.add"
        class="filter-item"
        size="mini"
        type="primary"
        icon="el-icon-plus"
        @click="addFuc"
      >
        新增
      </el-button>
    </div>
    <!-- 表单渲染 -->
    <el-dialog
      append-to-body
      :close-on-click-modal="false"
      :visible.sync="addShow"
      :title="myTitle"
      width="540px"
    >
      <el-form
        ref="form"
        :inline="true"
        :model="myForm"
        :rules="rules"
        size="small"
        label-width="100px"
      >
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="myForm.name" style="width: 380px" />
        </el-form-item>
        <el-form-item label="角色代码" prop="name">
          <el-input v-model="myForm.code" style="width: 380px" />
        </el-form-item>
        <el-form-item label="是否管理员" prop="isAdmin">
          <el-radio-group v-model="myForm.isAdmin" style="width: 178px">
            <el-radio :label="1">是</el-radio>
            <el-radio :label="0">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="描述信息" prop="remark">
          <el-input
            v-model="myForm.remark"
            style="width: 380px"
            rows="5"
            type="textarea"
          />
        </el-form-item>
        <el-form-item label="上级代码" prop="pcode">
          <el-input
            v-model="myForm.pcode"
            :disabled="true"
            style="width: 380px"
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" plain @click="addShow = false"
          >取消</el-button
        >
        <el-button :loading="submitStatus" type="primary" @click="confirm"
          >确定</el-button
        >
      </div>
    </el-dialog>
    <el-row :gutter="15">
      <!--角色管理-->
      <el-col
        :xs="24"
        :sm="24"
        :md="16"
        :lg="16"
        :xl="17"
        style="margin-bottom: 10px"
      >
        <el-card class="box-card" shadow="never">
          <div slot="header" class="clearfix">
            <span class="role-span">角色列表</span>
          </div>
          <el-table
            ref="table"
            v-loading="loading"
            highlight-current-row
            style="width: 100%"
            :data="tableData"
            row-key="id"
            @row-click="rowClick"
            @current-change="handleCurrentChange"
            @select="selectFuc"
            :max-height="tableHeight"
          >
            <el-table-column
              :selectable="checkboxT"
              :reserve-selection="true"
              type="selection"
              width="55"
            />
            <el-table-column
              prop="data.name"
              label="角色名称"
              :show-overflow-tooltip="true"
            />
            <el-table-column prop="data.code" label="角色代码" />
            <el-table-column prop="data.isAdmin" label="是否管理员">
              <template slot-scope="scope">
                <div v-for="item in dict.yesOrNot" :key="item.code">
                  <span v-if="item.code == scope.row.data.isAdmin">
                    {{ item.name }}
                  </span>
                </div>
              </template>
            </el-table-column>
            <el-table-column
              :show-overflow-tooltip="true"
              prop="data.remark"
              label="描述"
            />
            <el-table-column
              align="center"
              label="操作"
              width="200px"
              fixed="right"
            >
              <template slot-scope="scope">
                <el-button
                  size="mini"
                  class="filter-item"
                  type="success"
                  v-permission="['100', 'role:edit']"
                  @click="editFuc(scope.row)"
                  >&nbsp;修改
                </el-button>
                <el-button
                  size="mini"
                  class="filter-item"
                  type="danger"
                  v-permission="['100', 'role:del']"
                  @click="deleteFuc(scope.row)"
                  >&nbsp;删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
      <!-- 菜单授权 -->
      <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7">
        <el-card class="box-card" shadow="never">
          <el-tabs v-model="activeName">
            <el-tab-pane name="first" label="菜单分配">
              <el-button
                v-permission="['100', 'role:edit']"
                :disabled="!showButton"
                :loading="menuLoading"
                icon="el-icon-check"
                size="mini"
                type="primary"
                @click="saveMenu"
                style="margin-bottom: 10px"
                >保存
              </el-button>
              <el-tree
                ref="menu"
                :data="menus"
                :default-checked-keys="menuIds"
                :props="defaultProps"
                accordion
                show-checkbox
                node-key="id"
                @check="menuChange"
                :check-strictly="checkStrictlyVal"
              />
            </el-tab-pane>
            <el-tab-pane label="用户角色管理" name="second">
              <el-button
                type="primary"
                size="mini"
                :disabled="!currenRoleCode"
                @click="addUser"
                class="el-icon-plus"
              >
                &nbsp;新增绑定
              </el-button>
              <el-table :data="roleUserInfo" style="width: 100%">
                <el-table-column type="index" label="序号" width="50" />
                <el-table-column prop="name" label="姓名" />
                <el-table-column prop="account" label="账号" />
                <el-table-column prop="status" label="状态" width="50">
                  <template slot-scope="scope">
                    <div v-for="item in dict.userStatus" :key="item.code">
                      <span v-if="item.code == scope.row.status">
                        {{ item.name }}
                      </span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column prop="sex" label="性别" width="50">
                  <template slot-scope="scope">
                    <div v-for="item in dict.sex" :key="item.code">
                      <span v-if="item.code == scope.row.status">
                        {{ item.name }}
                      </span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column prop="sex" label="操作" width="80">
                  <template slot-scope="scope">
                    <el-button
                      type="success"
                      size="mini"
                      @click="removeUser(scope.row)"
                      >&nbsp;解绑</el-button
                    >
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </el-col>
    </el-row>
    <Detail
      @getRoleUserInfo="getRoleUserInfo"
      :postDetail="postDetailData"
      :userTreeData="deptUserTree"
    ></Detail>
  </div>
</template>

<script>
import crudRoles from "@/api/system/role";
import { getMenusTree } from "@/api/system/menu";

import Detail from "./user-detail";
import msgUtil from "@/utils/msgUtil";

const defaultForm = {
  id: null,
  code: null,
  pcode: null,
  name: null,
  type: 0,
  isAdmin: 0,
  dataScope: null,
  remark: null,
};
export default {
  name: "Role",
  components: { Detail },
  dicts: ["dateScopes", "yesOrNot", "userStatus", "sex"],
  data() {
    return {
      query: { name: "", type: "" },
      loading: true,
      tableData: [],
      page: {
        size: 30,
        total: 0,
        page: 1,
      },
      myTitle: "",
      addShow: false,
      myForm: {
        id: null,
        code: null,
        pcode: null,
        name: null,
        type: 0,
        isAdmin: 0,
        dataScope: null,
        remark: null,
      },
      submitStatus: false,
      //上面是优化代码
      detailType: "",
      tableHeight: "800px",
      selections: [],
      row: "",
      // 点击表格获取到角色代码的值
      currenRoleCode: "",
      currenRoleId: "",
      currenRoleName: "",
      location: "",
      selectValList: [],
      // 部门树
      deptUserTree: [],
      activeName: "first",
      roleUserInfo: [],
      checkStrictlyVal: false,
      defaultProps: { children: "children", label: "name" },
      level: 3,
      currentId: "0",
      menuLoading: false,
      showButton: false,
      menus: [],
      menuIds: [], // 多选时使用
      permission: {
        add: ["100", "role:add"],
        edit: ["100", "role:edit"],
        del: ["100", "role:del"],
      },
      rules: {
        name: [{ required: true, message: "请输入名称", trigger: "blur" }],
        permission: [
          { required: true, message: "请输入权限", trigger: "blur" },
        ],
      },
      postDetailData: {
        show: false,
        type: "edit",
        params: {},
      },
    };
  },
  created() {
    this.getMenuData();
    this.getMenusTree();
    this.getDeptUserTree();
    const winHeight = document.body.clientHeight;
    this.tableHeight = winHeight - 330;
    // 0正常角色， 1是流程角色
    // this.query.type = 0;
  },
  mounted() {
    this.getData();
  },
  methods: {
    resetGetData() {
      this.query = { name: "" };
      this.getData();
    },
    //刷新列表
    getData() {
      this.loading = true;
      this.query.pageNo = this.page.page-1;
      this.query.pageSize = this.page.size;
      crudRoles.getAll(this.query).then((res) => {
        if (res.code == 200) {
          this.loading = false;
          this.tableData = res.data;
          this.$refs.menu.setCheckedKeys([]);
        }
      });
    },

    addFuc() {
      this.myTitle = "新增角色";
      this.addShow = true;
      this.detailType = "add";
      this.myForm = {};
      if (this.selections.length) {
        this.myForm.pcode = this.selections[0].data.code;
        this.myForm.type = this.selections[0].data.type;
      } else {
        this.myForm.pcode = "0";
        this.myForm.type = "0";
      }

      this.$nextTick(() => {
        this.$refs["form"].clearValidate();
      });
    },
    editFuc(row) {
      this.myTitle = "编辑角色";
      this.addShow = true;
      this.detailType = "edit";
      if (row) {
        crudRoles.getOne(row.id).then((res) => {
          this.myForm = res.data;
        });
      }
    },
    deleteFuc(row) {
      msgUtil.confirm("确认删除该角色及其下属角色?").then(async () => {
        const ids = [];
        ids.push(row.id);
        await this.del(ids);
      });
    },
    del(ids) {
      crudRoles.del(ids).then((res) => {
        msgUtil.success2("删除成功!");
        this.getData();
      });
    },
    confirm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.submitStatus = true;
          if (this.detailType === "add") {
            this.myForm.type = 0;
            crudRoles.add(this.myForm).then((res) => {
              this.submitStatus = false;
              msgUtil.success2("新增成功!");
              this.addShow = false;
              this.getData();
            });
          } else if (this.detailType === "edit") {
            crudRoles.edit(this.myForm).then((res) => {
              this.submitStatus = false;
              msgUtil.success2("修改成功!");
              this.addShow = false;
              this.getData();
            });
          }
        }
      });
    },
    rowClick(row, index, e) {
      this.$refs.table.toggleRowExpansion(row);
    },
    rowKey(row) {
      return row.id;
    },
    //用户管理用户删除
    removeUser(row) {
      msgUtil.confirm("确认解除该用户角色绑定?").then((res) => {
        let params = {
          userIds: row.id,
          roleId: this.currentId,
        };
        crudRoles.unbindUserRole(params).then((res) => {
          msgUtil.success2("解除绑定成功!");
          this.getRoleUserInfo(this.currentId);
        });
      });
    },
    // 用户管理新增
    addUser() {
      this.postDetailData = {
        show: true,
        type: "edit",
        params: {
          roleId: this.currenRoleId,
          roleCode: this.currenRoleCode,
          roleName: this.currenRoleName,
          location: this.location,
        },
      };
    },
    getDeptUserTree() {
      crudRoles.getDeptUserTree().then((res) => {
        this.deptUserTree = res.data;
        console.log(this.deptUserTree);
      });
    },
    selectFuc(selection, row) {
      let oldSelect = this.$refs.table.selection;
      if (oldSelect.length === 0) {
        this.$refs.table.toggleRowSelection(row, false);
      } else {
        this.handleCurrentChange(row, selection[0]);
      }
    },
    getMenusTree() {
      const param = { type: 0 };
      getMenusTree(param).then((res) => {
        this.menus = res.data;
      });
    },
    getMenuData(id) {
      this.checkStrictlyVal = true;
      crudRoles
        .getMenu({ id: id })
        .then((res) => {
          this.menuIds = res.data;
        })
        .finally(() => {
          this.checkStrictlyVal = false;
        });
    },

    // 触发单选
    handleCurrentChange(selection, row) {
      this.row = row;
      this.currenRoleId = selection.data.id;
      this.currenRoleCode = selection.data.code;
      this.currenRoleName = selection.data.name;
      this.$refs.table.clearSelection(); //清空之前勾选的
      this.$refs.table.toggleRowSelection(row, false); //单选则将之前的选项勾掉
      this.$refs.table.toggleRowSelection(selection, true); //单选则将选项勾上
      this.selections = this.$refs.table.selection;
      if (selection) {
        // 清空菜单的选中
        this.$refs.menu.setCheckedKeys([]);
        // 保存当前的角色id
        this.currentId = selection.id;
        // 初始化默认选中的key
        this.getMenuData(selection.data.id);
        this.getRoleUserInfo(this.currentId);
        this.showButton = true;
      }
    },
    getRoleUserInfo(roleId) {
      crudRoles.getRoleUserInfo(roleId).then((res) => {
        this.roleUserInfo = res.data.roleUserInfo;
        this.location = res.data.location;
      });
    },

    menuChange(menu) {
      // let thisNode = this.$refs.menu.getNode(menu.id) // 获取当前节点
      // if (thisNode.checked) { // 当前节点若被选中
      //   const id = thisNode.data.id
      //
      // }
      this.menuIds = this.$refs.menu.getCheckedKeys();
    },
    // 保存菜单
    saveMenu() {
      this.menuLoading = true;
      const role = { id: this.currentId, menus: [] };
      // 得到已选中的 key 值
      this.menuIds.forEach(function (id) {
        role.menus.push(id);
      });
      //子选项未全选时，获取父节点编码
      let menuHalfIds = this.$refs.menu.getHalfCheckedKeys();
      menuHalfIds.forEach((id) => {
        if (role.menus.indexOf(id) == -1) {
          role.menus.push(id);
        }
      });
      crudRoles
        .editMenu(role)
        .then(() => {
          this.$notify({
            title: "成功",
            message: "保存成功",
            type: "success",
          });

          this.menuLoading = false;
        })
        .catch((err) => {
          this.menuLoading = false;
          console.log(err.response.data.message);
        });
    },

    checkboxT(row) {
      return true;
    },
  },
};
</script>

<style rel="stylesheet/scss" lang="scss">
.role-span {
  font-weight: bold;
  color: #303133;
  font-size: 15px;
}
</style>

<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
  text-align: left;
}

::v-deep .vue-treeselect__multi-value {
  margin-bottom: 0;
}

::v-deep .vue-treeselect__multi-value-item {
  border: 0;
  padding: 0;
}
</style>
